import {
	IAppFunc,
	IAppFuncHelper,
	IContext,
	IParam,
	computedNavData,
	deepCopy,
} from '@/core';
import { router } from '@/router';
import { getIndexRoutePath } from '@/utils';

export class AppFuncHelper implements IAppFuncHelper {
	/**
	 * @description 单例变量声明
	 * @protected
	 * @static
	 * @type {IAppFuncHelper}
	 * @memberof AppFuncHelper
	 */
	protected static service: IAppFuncHelper;

	/**
	 * @description 获取实例
	 * @static
	 * @return {*}  {IAppFuncHelper}
	 * @memberof AppFuncHelper
	 */
	static getInstance(): IAppFuncHelper {
		if (!this.service) {
			this.service = new AppFuncHelper();
		}
		return this.service;
	}

	/**
	 * @description 执行应用功能
	 * @param {string} appFuncTag 应用功能
	 * @param {(IContext | undefined)} [context] 应用上下文
	 * @param {(IParam | undefined)} [viewParams] 视图参数
	 * @return {*}  {void}
	 * @memberof AppFuncHelper
	 */
	execute(
		appFuncTag: string,
		context?: IContext | undefined,
		viewParams?: IParam | undefined
	): void {
		const appFunc = this.getAppFunc(appFuncTag);
		if (appFunc) {
			const temContext = context ? deepCopy(context) : {};
			if (context && appFunc.navigateContext) {
				const localContext = computedNavData(
					{},
					context,
					viewParams,
					appFunc.navigateContext
				);
				Object.assign(temContext, localContext);
			}
			const temViewParams = viewParams ? deepCopy(viewParams) : {};
			if (viewParams && appFunc.navigateParam) {
				const localViewParam = computedNavData(
					{},
					context,
					viewParams,
					appFunc.navigateParam
				);
				Object.assign(temViewParams, localViewParam);
			}
			switch (appFunc.appFuncType) {
				case 'APPVIEW':
					this.openAppView(appFunc, temContext, temViewParams);
					return;
				case 'OPENHTMLPAGE':
					this.openHtmlPage(appFunc, temContext, temViewParams);
					return;
				case 'PDTAPPFUNC':
					this.openPdAppFunc(appFunc, temContext, temViewParams);
					return;
				case 'JAVASCRIPT':
					this.executeJavaScript(appFunc, temContext, temViewParams);
					return;
				case 'CUSTOM':
					this.executeCustom(appFunc, temContext, temViewParams);
					return;
				default:
					console.warn('无该应用功能');
			}
		}
	}

	/**
	 * @description 打开视图
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	openAppView(appFunc: IAppFunc, context: IContext, viewParams: IParam): void {
		const viewCodeName = appFunc.openViewCodeName;
		if (viewCodeName) {
			const appViewConfig = App.getAppViewConfig();
			const view = appViewConfig[viewCodeName];
			if (view) {
				App.getOpenViewHelper().openPage(view, context, viewParams);
			} else {
				console.warn('未找到相关视图');
			}
		} else {
			console.warn('应用功能无打开视图');
		}
	}

	/**
	 * @description 打开Html页面
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	openHtmlPage(appFunc: IAppFunc, context: IContext, viewParams: IParam): void {
		const { htmlPageUrl, openMode, name } = appFunc;
		switch (openMode) {
			case 'INDEXVIEWTAB':
			case 'TOP':
				if (htmlPageUrl) {
					const { currentRoute, push } = router;
					const indexPath = getIndexRoutePath(currentRoute.value);
					let path = `${indexPath}/apphtmlview/${encodeURIComponent(
						htmlPageUrl
					)}`;
					if (name) {
						path += `?caption=${encodeURIComponent(name)}`;
					}
					push(path);
				}
				break;
			case 'INDEXVIEWPOPUP':
			case 'INDEXVIEWPOPUPMODAL':
				const view = {
					name: 'app-html-container',
					caption: name || '应用HTML视图',
					codeName: 'AppHtmlContainer',
					openMode: 'POPUPMODAL',
					height: 800,
					width: 1200,
				};
				Object.assign(viewParams, { caption: name, htmlPageUrl });
				App.getOpenViewHelper()
					.openModal(view, context, viewParams)
					.catch((error: any) => {
						App.getNotificationHelper().error(
							App.ts(
								'app.helper.openhtmlfail',
								'Failed to open html view in mode'
							)
						);
					});
				break;
			case 'HTMLPOPUP':
				window.open(htmlPageUrl, '_blank');
				break;
			default:
				window.open(htmlPageUrl, '_blank');
				break;
		}
	}

	/**
	 * @description 处理预制应用功能
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	openPdAppFunc(
		appFunc: IAppFunc,
		context: IContext,
		viewParams: IParam
	): void {
		// todo 类型标识待补充
		if (appFunc.name) {
			switch (appFunc.name) {
				case '系统登录':
					App.login();
					break;
				case '系统登出':
					App.logout();
					break;
				case '清空缓存':
					App.clearAppData();
					break;
				case '检查系统更新':
					console.warn('暂未实现');
					break;
				case '关于系统':
					App.aboutSystem();
					break;
				case '我的收藏':
					console.warn('暂未实现');
					break;
			}
		}
	}

	/**
	 * @description 执行JavaScript
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	executeJavaScript(
		appFunc: IAppFunc,
		context: IContext,
		viewParams: IParam
	): void {
		console.warn('执行JS暂不支持');
	}

	/**
	 * @description 自定义
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	executeCustom(
		appFunc: IAppFunc,
		context: IContext,
		viewParams: IParam
	): void {
		console.warn('自定义暂不支持');
	}

	/**
	 * @description 执行界面行为
	 * @param {IAppFunc} appFuncTag 应用功能
	 * @param {IContext} [context] 应用上下文
	 * @param {IParam} [viewParams] 视图参数
	 * @memberof AppFuncHelper
	 */
	executeAppUIAction(
		appFunc: IAppFunc,
		context: IContext,
		viewParams: IParam
	): void {
		// todo 界面行为
	}

	/**
	 * @description 获取应用功能
	 * @param {string} appFuncTag 应用功能
	 * @return {*}  {(IAppFunc | null | undefined)}
	 * @memberof AppFuncHelper
	 */
	public getAppFunc(appFuncTag: string): IAppFunc | null | undefined {
		const appFuncConfig = App.getAppFuncConfig();
		if (appFuncConfig && appFuncConfig.length > 0) {
			return appFuncConfig.find((appFunc: IAppFunc) => {
				return appFunc.funcTag === appFuncTag;
			});
		}
		return null;
	}
}
